package ar.com.fiuba.team2.parser;

import java.io.IOException;
import java.io.StringReader;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import ar.com.fiuba.team2.model.Result;

public abstract class GeneralParser {

	private static final String RESULT_OK = "2";
	private static Logger log = LogManager.getLogger(GeneralParser.class);
	
	/**
	 * Resuelve el resultado de las operacioens de actualzación de la forma:
	 * <pre>
	 * &lt;notificacion&gt; 
	 *   &lt;numero/&gt;
	 *   &lt;mensaje/&gt;
	 *   (&lt;data/&gt;)
	 * &lt;/notificacion&gt; 
	 * </pre>
	 * Aparte puede devolver el resultado (numero y mensaje) en el elemento Result.
	 * 
	 * @param resultXML
	 * @param result
	 * @return id de la operación realizada fue existosa y si existe, -1 sino.
	 */
	public static long parseResultado(String resultXML, Result result) {
		SAXBuilder saxBuilder = new SAXBuilder();
		long id = -1;
		
		try {
			Document doc = saxBuilder.build(new StringReader(resultXML));
			String message = extractString(doc.getRootElement(), "numero");
			if (result != null) {
				result.setCode(message);
				result.setDescription(extractString(doc.getRootElement(), "mensaje"));
			}
			Long data = extractLong(doc.getRootElement(), "datos");
			if (RESULT_OK.equals(message) && data != null) {
				id = data;
			}
		} catch (JDOMException e) {
			log.error("error al parsear resultado " + result, e);
		} catch (IOException e) {
			log.error("error al parsear resultado " + result, e);
		} catch (NumberFormatException e) {
			log.error("error al parsear id de " + result, e);
		}
		return id;
	}


	/**
	 * Busca el nodo, si existe devuelve el valor.
	 * 
	 * @param childXML
	 * @return string si existe o null.
	 */
	public static String extractString(Element childXML, String label) {
		return extractString(childXML, label, null);
	}

	/**
	 * Busca el nodo, si existe devuelve el valor.
	 * 
	 * @param childXML
	 * @return string si existe o el defaultStr.
	 */
	public static String extractString(Element childXML, String label, String defaultStr) {
		Element child = childXML.getChild(label);
		String text = null;
		if (child != null) {
			text = child.getText();
		}
		return text == null ? defaultStr : text;
	}

	/**
	 * Busca el nodo, si existe devuelve el valor.
	 * 
	 * @param childXML
	 * @return long si existe o null.
	 */
	public static Long extractLong(Element childXML, String label) {
		Element child = childXML.getChild(label);
		String text = null;
		if (child != null) {
			text = child.getText();
		}
		return text == null ? null : Long.valueOf(text);
	}
}
